/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.yaps.petstore.dao.impl;

import com.yaps.petstore.dao.CategoryDAO;
import com.yaps.petstore.dao.ProductDAO;
import com.yaps.petstore.entity.catalog.Category;
import com.yaps.petstore.entity.catalog.Product;
import com.yaps.petstore.exception.ValidationException;
import com.yaps.petstore.util.Constants;
import java.util.List;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository("ProductDAO")
public class ProductDAOImpl implements ProductDAO  {
	@PersistenceContext
	private EntityManager em;

    private final String cname = this.getClass().getName();
    private Logger logger = Logger.getLogger(Constants.LOGGER_STATELESS);
    
    
     // ======================================
    // = Methodes publiques pour produit    =
    // ======================================
    @Override
    @Transactional
    public Product createProduct(final Product product, final Category category) {
        final String mname = "createProduct";
        logger.entering(cname, mname, product);

        // On s'assure de la validité des paramètres
        if (product == null)
            throw new ValidationException("Product object is null");
        if (category == null)
            throw new ValidationException("Product must be attached to a category");

        product.setCategory(category);

        // L'objet est persisté en base de données
        em.persist(product);

        logger.exiting(cname, mname, product);
        return product;
    }

    
    @Override
    public Product findProduct(final Long productId) {
        final String mname = "findProduct";
        logger.entering(cname, mname, productId);

        // On s'assure de la validité des paramètres
        if (productId == null)
            throw new ValidationException("Invalid id");

        Product product;

        // On recherche l'objet à partir de son identifiant
        product = em.find(Product.class, productId);

        logger.exiting(cname, mname, product);
        return product;
    }

    
    @Transactional
    @Override
    public void deleteProduct(final Product product) {
        final String mname = "deleteProduct";
        logger.entering(cname, mname, product);

        // On s'assure de la validité des paramètres
        if (product == null)
            throw new ValidationException("Product object is null");

        // On supprime l'objet de la base de données
        em.remove(em.merge(product));

        logger.exiting(cname, mname);
    }

    
    @Transactional
    @Override
    public Product updateProduct(final Product product, final Category category) {
        final String mname = "updateProduct";
        logger.entering(cname, mname, product);

        // On s'assure de la validité des paramètres
        if (product == null)
            throw new ValidationException("Product object is null");
        if (category == null)
            throw new ValidationException("Product must be attached to a category");

        product.setCategory(category);

        // On modifie l'objet de la base de données
        em.merge(product);

        logger.exiting(cname, mname, product);
        return product;
    }

    @Override
    public List<Product> findProducts() {
        final String mname = "findCategories";
        logger.entering(cname, mname);

        
        List<Product> products;
        // On modifie l'objet de la base de données
        Query query = em.createQuery("SELECT p FROM Product p ORDER BY p.name");
        products = query.getResultList();

        logger.exiting(cname, mname, products.size());
        return products;
    }

    
}
